package com.weifei.core.aop;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 用来解析和封装AOP配置
 */
public class WFAdvisedSupport {

    private Class targetClass;
    private Object target;
    private Pattern pointCutClassPattern;
    private Map<Method, List<Object>> methodCache;

    private WFAopConfig aopConfig;

    public WFAdvisedSupport(WFAopConfig aopConfig) {
        this.aopConfig = aopConfig;
    }

    public Class getTargetClass() {
        return targetClass;
    }

    public void setTargetClass(Class targetClass) {
        this.targetClass = targetClass;
    }

    public Object getTarget() {
        return target;
    }

    public void setTarget(Object target) {
        this.target = target;
    }

    private void parse() {
        String pointCut = aopConfig.getPointCut()
                .replaceAll("\\.", "\\\\.")
                .replaceAll("\\\\.\\*", ".*")
                .replaceAll("\\(", "\\\\(")
                .replaceAll("\\)", "\\\\)");
        String pointCutForClass = pointCut.substring(0, pointCut.lastIndexOf("\\(") -4);
        pointCutClassPattern = Pattern.compile("class " + pointCutForClass
                .substring(pointCutForClass.lastIndexOf(" ") +1));
        methodCache = new HashMap<>();
        Pattern pattern = Pattern.compile(pointCut);
        try {
            Class aspectClass = Class.forName(aopConfig.getAspectClass());
            Map<String, Method> aspectMethods = new HashMap<>();
            for (Method m : aspectClass.getMethods()) {
                aspectMethods.put(m.getName(), m);
            }

            //收集原生方法
            for (Method m : targetClass.getMethods()) {
                String methodString = m.toString();
                if (methodString.contains("throws")) {
                    methodString = methodString.substring(0, methodString.indexOf("throws")).trim();
                }
                Matcher matcher = pattern.matcher(methodString);
                if (matcher.matches()) {
                    //满足切面规则的类，添加到AOP配置中
                    List<Object> advices = new LinkedList<>();
                    //配置了前置通知
                    if (!(null == aopConfig.getAspectBefore() || "".equals(aopConfig.getAspectBefore().trim()))) {
                        advices.add(new WFMethodBeforeAdvice(aspectMethods
                                .get(aopConfig.getAspectBefore()), aspectClass.newInstance()));
                    }
                    //后置通知
                    if (!(null == aopConfig.getAspectAfter()
                            || "".equals(aopConfig.getAspectAfter().trim()))) {

                    }
                    //异常通知
                    if (!(null == aopConfig.getAspectAfterThrow() ||
                    "".equals(aopConfig.getAspectAfterThrow().trim()))) {

                    }

                    methodCache.put(m, advices);

                }
             }


        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public List<Object> getInterceptorsAndDynamicInterceptionAdivice(Method method, Class targetClass) throws NoSuchMethodException {
        List<Object> cached = methodCache.get(method);
        if (cached == null) {
            Method m = targetClass.getMethod(method.getName(), method.getParameterTypes());
            cached = methodCache.get(method);
            methodCache.put(m, cached);
        }
        return cached;

    }
}
